<?php
/**
 * appRain v 0.1.x
 *
 * LICENSE
 *
 * This source file is subject to the MIT license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://www.opensource.org/licenses/mit-license.php
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@apprain.com so we can send you a copy immediately.
 *
 * @copyright  Copyright (c) 2010 appRain, Team. (http://www.apprain.com)
 * @license    http://www.opensource.org/licenses/mit-license.php MIT license
 *
 * HELP
 *
 * Official Website
 * http://www.apprain.com/
 *
 * Download Link
 * http://www.apprain.com/download
 *
 * Documents Link
 * http ://www.apprain.com/docs
 */


class appRain_Base_Modules_Event
{
	private $callbacks;

	public function __construct()
	{
		$this->callbacks = array();
	}

	private function Get_Callback($args)
	{
		return (count($args) < 2) ? new Callback($args[0], '') : new Callback($args[1], get_class($args[0]));
	}

	public function Subscribe()
	{
		$callback = $this->Get_Callback(func_get_args());
		if (!in_array($callback, $this->callbacks))
		{
			$this->callbacks[] = $callback;
		}
		else throw new Exception($callback->method.' already subscribed to this event');
	}

	public function Unsubscribe()
	{
		$callback = $this->Get_Callback(func_get_args());
		$key = array_search($callback, $this->callbacks);
		if (!($key === false))
		{
			unset($this->callbacks[$key]);
		}
		else throw new Exception($callback->method.' not subscribed to this event');
	}

	public function Raise()
	{
		foreach($this->callbacks as $callback)
		{
			if (method_exists($callback->context, $callback->method) || function_exists($callback->method))
			{
				$params = func_get_args();
				$callback = (!empty($callback->context)) ? array($callback->context, $callback->method) : $callback->method;
				call_user_func_array($callback, $params);
			}
			else throw new Exception($callback->method." does not exist");
		}
	}
}

class Callback
{
	public $method;
	public $context;

	public function Callback($method, $context)
	{
		$this->method = $method;
		$this->context = $context;
	}
}